package net.wicp.tams.common.binlog.self.replication.up.command;

import java.util.Collection;

import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.ByteUtil.AssitWrite;
import net.wicp.tams.common.binlog.self.GtidSet;
import net.wicp.tams.common.binlog.self.constant.Command;

public class ComBinlogDumpGtid extends AbsCommand {
	private static final long serialVersionUID = 1L;
	private long serverId;
	private String binlogFilename = "";
	private long binlogPos = 4;
	private GtidSet gtidSet;

	/*
	 * private enum Flags { BINLOG_DUMP_NON_BLOCK((byte) 0x01),
	 * BINLOG_THROUGH_POSITION((byte) 0x02), BINLOG_THROUGH_GTID((byte) 0x04);
	 * 
	 * private final byte value;
	 * 
	 * public byte getValue() { return value; }
	 * 
	 * private Flags(byte value) { this.value = value; } }
	 */

	public ComBinlogDumpGtid() {
		super(Command.COM_BINLOG_DUMP_GTID);
	}

	@Override
	public void packPacket(AssitWrite assit) {
		assit.write(command.getValue(), 1);
		assit.write(0, 2);// flag
		assit.write(serverId, 4);
		assit.write(binlogFilename.length(), 4);
		assit.write(binlogFilename);
		assit.write(binlogPos, 8);

		Collection<GtidSet.UUIDSet> uuidSets = gtidSet.getUUIDSets();
		int dataSize = 8 /* number of uuidSets */;
		for (GtidSet.UUIDSet uuidSet : uuidSets) {
			dataSize += 16 /* uuid */ + 8 /* number of intervals */ + uuidSet.getIntervals().size()
					/* number of intervals */ * 16 /* start-end */;
		}
		assit.write(dataSize, 4);
		assit.write((long) uuidSets.size(), 8);

		for (GtidSet.UUIDSet uuidSet : uuidSets) {
			// assit.write(uuidSet.getUUID().replace("-", ""));
			assit.write(hexToByteArray(uuidSet.getUUID().replace("-", "")));
			Collection<GtidSet.Interval> intervals = uuidSet.getIntervals();
			assit.write((long) intervals.size(), 8);
			for (GtidSet.Interval interval : intervals) {
				assit.write((long) interval.getStart(), 8);
				assit.write((long) interval.getEnd() + 1 /* right-open */, 8);
			}
		}
	}

	private static byte[] hexToByteArray(String uuid) {
		byte[] b = new byte[uuid.length() / 2];
		for (int i = 0, j = 0; j < uuid.length(); j += 2) {
			b[i++] = (byte) Integer.parseInt(uuid.charAt(j) + "" + uuid.charAt(j + 1), 16);
		}
		return b;
	}

	@Override
	protected Result check() {
		if (gtidSet == null) {
			return Result.getError("need gtid");
		}
		return Result.getSuc();
	}

	public GtidSet getGtidSet() {
		return gtidSet;
	}

	public void setGtidSet(GtidSet gtidSet) {
		this.gtidSet = gtidSet;
	}

	public long getServerId() {
		return serverId;
	}

	public void setServerId(long serverId) {
		this.serverId = serverId;
	}

	public String getBinlogFilename() {
		return binlogFilename;
	}

	public void setBinlogFilename(String binlogFilename) {
		this.binlogFilename = binlogFilename;
	}

	public long getBinlogPos() {
		return binlogPos;
	}

	public void setBinlogPos(long binlogPos) {
		this.binlogPos = binlogPos;
	}
}
